package com.hubei.car.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * token工具类
 * @author luokangtao
 * @create 2019-07-23 12:30
 */
@Slf4j
@Component
public class JwtUtil {
    //秘钥  (因为拦截器是common包,所以要设置个初始值,跟user模块设置的key值要一样)
    @Value("${jwt.key}")
    private String key;
    //过期时间毫秒值
    @Value("${jwt.ttl}")
    private long ttl ;

    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public long getTtl() {
        return ttl;
    }
    public void setTtl(long ttl) {
        this.ttl = ttl;
    }


    /**
     * 生成JWT 签发JWT
     *
     * @param id JWT_id
     * @param subject 主题
     * @param roles 角色
     * @return
     */
    public String createJWT(String id, String subject, String roles,String type) {
        log.info("jwt的key值:[{}],过期时间ttl:[{}]",key,ttl);
        //获取当前系统时间毫秒值
        long nowMillis = System.currentTimeMillis();
        //转换时间
        Date now = new Date(nowMillis);
        //这里其实就是new一个JwtBuilder，设置jwt的body
        JwtBuilder builder = Jwts.builder()
                //设置jti(JWT ID)：是JWT的唯一标识，根据业务需要，这个可以设置为一个不重复的值，主要用来作为一次性token,从而回避重放攻击。
                .setId(id)
                //sub(Subject)：代表这个JWT的主体，即它的所有人，这个是一个json格式的字符串，可以存放什么userid，roldid之类的，作为什么用户的唯一标志。
                .setSubject(subject)
                //iat: jwt的签发时间
                .setIssuedAt(now)
                //设置签名使用的签名算法和签名使用的秘钥
                .signWith(SignatureAlgorithm.HS512, key)
                //自定义的属性(一般定义角色)
                .claim("roles", roles)
                //判断是账户登陆,还是第三方授权登陆
                .claim("type",type);

        if (ttl > 0) {
            //设置过期时间
            builder.setExpiration( new Date( nowMillis + ttl));
        }
        //返回Jwts
        return builder.compact();
    }


    /**
     * 解析JWT
     * @param jwtStr
     * @return
     */
    public Claims parseJWT(String jwtStr){
        log.info("jwt的key值:[{}],过期时间ttl:[{}]",key,ttl);
        return Jwts.parser()
                //设置签名的秘钥，和生成的签名的秘钥一模一样
                .setSigningKey(key)
                //设置需要解析的jwt
                .parseClaimsJws(jwtStr)
                //获取实体
                .getBody();
    }
}





